#ifndef UNIFIEDPAGERENDERER_H
#define UNIFIEDPAGERENDERER_H

#include <QObject>
#include <QRect>
#include <QString>
#include <QList>
#include <QVector>
#include <QHash>
#include <QSize>

#include <QImage>
#include <QPainter>
#include <QFont>
#include <QColor>
#include <QPdfWriter>
#include "layoutstatemanager.h"
#include "pagepositionsystem.h"
#include "pagerendercontext.h"

// 前向声明，避免循环包含
struct ProcessingSettings;
class QScreen;

/**
 * UnifiedPageRenderer - 统一页面渲染器
 * 职责：统一处理预览和导出的渲染逻辑，确保所见即所得
 */
class UnifiedPageRenderer : public QObject
{
    Q_OBJECT

public:
    // 页面布局信息
    struct PageLayout {
        QRect pageRect;           // 整个页面区域
        QRect contentArea;        // 内容区域（扣除边距）
        QRect marginAreas[4];     // 上下左右边距区域 [上,下,左,右]
        QRect pageNumberArea;     // 页码区域
        QRect headerArea;         // 页眉区域
        QRect footerArea;         // 页脚区域
    };

    explicit UnifiedPageRenderer(QObject* parent = nullptr);
    ~UnifiedPageRenderer();

    // === Martin Fowler重构：双画布渲染接口 ===

    /**
     * 设置渲染参数（重构后兼容接口）
     * @param settings 处理设置
     */
    void setRenderSettings(const ProcessingSettings& settings);

    /**
     * 设置页面内容（重构后兼容接口）
     * @param pageContent 页面内容图像
     */
    void setPageContent(const QImage& pageContent);

    // === 新的双画布渲染接口 ===

    /**
     * 渲染到显示器（使用物理画布）
     * Martin Fowler: Replace Method - 用双缓冲方法替换直接渲染
     * @param painter 绘制器
     * @param targetRect 目标矩形
     * @param content 页面内容
     * @param pageNumber 页码
     * @param totalPages 总页数
     */
    void renderToWidget(QPainter* painter, const QRect& targetRect, const QImage& content,
                       int pageNumber = 0, int totalPages = 0);

    /**
     * 渲染到PDF（使用虚拟画布）
     * @param writer PDF写入器
     * @param painter 绘制器
     * @param content 页面内容
     * @param pageNumber 页码
     * @param totalPages 总页数
     */
    void renderToPDF(QPdfWriter* writer, QPainter* painter, const QImage& content,
                    int pageNumber = 0, int totalPages = 0);

    /**
     * 兼容性接口：渲染到显示器（旧接口）
     * @deprecated 请使用新的双画布接口
     */
    void renderToWidget(QPainter* painter, const QRect& targetRect, int pageNumber, int totalPages = 0);

    /**
     * 兼容性接口：渲染到PDF（旧接口）
     * @deprecated 请使用新的双画布接口
     */
    void renderToPDF(QPdfWriter* writer, QPainter* painter, int pageNumber, int totalPages = 0);

    // === DPI和配置控制 ===

    /**
     * 设置处理DPI（影响虚拟画布分辨率）
     * @param dpi 新的处理DPI
     */
    void setProcessingDpi(double dpi);

    /**
     * 获取当前处理DPI
     * @return 当前处理DPI
     */
    double getProcessingDpi() const;

    /**
     * 自动配置渲染器以适应当前显示器
     * @param screen 目标屏幕，nullptr表示主屏幕
     */
    void autoConfigureForDisplay(QScreen* screen = nullptr);

    /**
     * 验证所见即所得一致性
     * @return 如果预览与导出一致返回true
     */
    bool verifyWYSIWYG() const;

    /**
     * 获取WYSIWYG验证详细报告
     * @return 格式化的验证报告字符串
     */
    QString getWYSIWYGReport() const;

    // 新增：多栏布局支持（从PageRenderer迁移）
    QList<QImage> rearrangePagesForColumns(const QList<QImage>& originalPages, LayoutMode mode);
    
    // 新增：组合页面生成（从PageRenderer迁移）
    QImage composeCompositePageAt(const QList<QImage>& originalPages, int compositeIndex, LayoutMode mode);
    
    // 新增：垂直流布局渲染（从PageRenderer迁移）
    QImage renderVerticalFlowLayout(const QList<QList<QImage>>& columnImages,
                                   const QList<int>& columnImageWidths,
                                   int columns, int columnWidth, int columnSpacing,
                                   int marginTop, int marginLeft, int marginBottom,
                                   int a4Width, int a4Height, int availableHeight,
                                   const QVector<int>* originalIndices = nullptr,
                                   QHash<int, QRect>* outOriginalToRect = nullptr);

    // 新增：页面计数方法（从PageRenderer迁移）
    int pagesPerComposite(LayoutMode mode) const;
    
    // 新增：带布局信息的页面重排（兼容PageRenderer接口）
    struct CompositeLayout {
        QList<QImage> pages;
        QHash<int, QHash<int, QRect>> layoutRects;
    };
    CompositeLayout rearrangeWithLayout(const QList<QImage>& originalPages, LayoutMode mode);

    // 获取当前设置
    const ProcessingSettings* getCurrentSettings() const;

    // === 双画布系统信息 ===

    /**
     * 获取渲染器调试信息
     * @return 格式化的调试信息
     */
    QString getDebugInfo() const;

    // 新增：高亮功能支持（从PageView迁移）
    void setHighlightInfo(int thumbnailIndex, int totalThumbnails, int columnMode);
    void clearHighlight();
    /**
     * @brief 计算高亮矩形区域
     * @param pageWidth 页面宽度
     * @param pageHeight 页面高度
     * @param currentPage 当前页面索引
     * @return 高亮矩形区域
     */
    QRect calculateHighlightRect(int pageWidth, int pageHeight, int currentPage) const;
    
    /**
     * @brief 绘制高亮矩形
     * @param painter 绘制器
     * @param pageRect 页面矩形区域
     * @param currentPage 当前页面索引
     */
    void drawHighlightRectangles(QPainter* painter, const QRect& pageRect, int currentPage) const;

    // 新增：智能缩放策略（从PageView迁移）
    enum ZoomStrategy {
        FitWidth,
        FitHeight,
        SmartFit
    };
    /**
     * @brief 计算最优缩放策略
     * @param image 源图像
     * @param viewSize 视图大小
     * @return 推荐的缩放策略
     */
    ZoomStrategy calculateOptimalZoomStrategy(const QImage& image, const QSize& viewSize) const;
    
    /**
     * @brief 计算缩放比例
     * @param image 源图像
     * @param viewSize 视图大小
     * @param strategy 缩放策略
     * @return 缩放比例
     */
    double calculateOptimalZoomRatio(const QImage& image, const QSize& viewSize, ZoomStrategy strategy) const;
    
    /**
     * @brief 判断是否应该优先使用适应宽度
     * @param imageRatio 图像宽高比
     * @param viewRatio 视图宽高比
     * @param image 源图像
     * @param viewSize 视图大小
     * @return 是否优先使用适应宽度
     */
    bool shouldPreferFitWidth(double imageRatio, double viewRatio, const QImage& image, const QSize& viewSize) const;

    // 新增：精确布局矩形支持（从PageView迁移）
    void setAccurateLayoutRects(const QHash<int, QHash<int, QRect>>& layoutRects);
    void clearAccurateLayoutRects();

    // 新增：预览渲染优化（从PageView迁移）
    /**
     * @brief 渲染预览图像
     * @param originalImage 原始图像
     * @param pageIndex 页面索引
     * @param targetSize 目标尺寸
     * @return 预览图像
     */
    QImage renderForPreview(const QImage& originalImage, int pageIndex, const QSize& targetSize, int totalPages = 0) const;

    /**
     * @brief 预览渲染（使用全局页码）
     * @param originalImage 原始图像
     * @param pageIndex 页面索引
     * @param targetSize 目标尺寸
     * @param globalPage 全局页码
     * @param totalPages 总页数
     * @return 预览图像
     */
    QImage renderForPreviewWithGlobalPage(const QImage& originalImage, int pageIndex, const QSize& targetSize, int globalPage, int totalPages) const;
    
    /**
     * @brief 渲染导出图像
     * @param originalImage 原始图像
     * @param pageIndex 页面索引
     * @return 导出图像
     */
    QImage renderForExport(const QImage& originalImage, int pageIndex, int totalPages = 0) const;

    // === Martin Fowler重构：使用PageRenderContext的新接口 ===

    /**
     * @brief 重构后的预览渲染（推荐使用）
     * @param originalImage 原始图像
     * @param context 页面渲染上下文（封装页码、总数、视口）
     * @return 预览图像
     */
    QImage renderForPreviewWithContext(const QImage& originalImage, const PageRenderContext& context) const;

    /**
     * @brief 重构后的导出渲染（推荐使用）
     * @param originalImage 原始图像
     * @param context 页面渲染上下文
     * @return 导出图像
     */
    QImage renderForExportWithContext(const QImage& originalImage, const PageRenderContext& context) const;
    
    /**
     * @brief 仅绘制页码部分，用于局部更新
     * @param painter 绘制器
     * @param targetRect 目标矩形
     * @param pageNumber 页码
     * @param totalPages 总页数
     */
    void renderPageNumberOnly(QPainter* painter, const QRect& targetRect, int pageNumber, int totalPages);

signals:
    void renderingStarted();
    void renderingFinished();

    /**
     * WYSIWYG验证结果发出
     * @param isValid 是否有效
     */
    void wysiwygValidationResult(bool isValid);

private:
    // ========== 渲染核心方法组 ==========
    /**
     * @brief 绘制页面内容
     * @param painter 绘制器
     * @param contentArea 内容区域
     */
    void drawPageContent(QPainter* painter, const QRect& contentArea);
    
    /**
     * @brief 绘制页面边距
     * @param painter 绘制器
     * @param layout 页面布局
     */
    void drawPageMargins(QPainter* painter, const PageLayout& layout);
    
    /**
     * @brief 绘制页码
     * @param painter 绘制器
     * @param layout 页面布局
     * @param pageNumber 页码
     * @param totalPages 总页数
     */
    void drawPageNumber(QPainter* painter, const PageLayout& layout, int pageNumber, int totalPages);
    
    void renderPageNumberDirect(QPainter* painter, const PageLayout& layout, int pageNumber, int totalPages);

    /**
     * @brief 绘制页眉页脚
     * @param painter 绘制器
     * @param layout 页面布局
     */
    void drawHeaderFooter(QPainter* painter, const PageLayout& layout);
    
  
    // ========== 布局计算方法组 ==========
    /**
     * @brief 计算页面布局
     * @param targetRect 目标矩形区域
     * @return 页面布局信息
     */
    PageLayout calculatePageLayout(const QRect& targetRect) const;
    
    /**
     * @brief 计算页码区域
     * @param layout 页面布局
     * @param position 页码位置（使用统一枚举）
     * @return 页码区域矩形
     */
    QRect calculatePageNumberArea(const PageLayout& layout, PagePositionSystem::Position position) const;
    
    /**
     * @brief 格式化页码文本
     * @param pageNumber 页码
     * @param totalPages 总页数
     * @return 格式化后的页码文本
     */
    QString formatPageNumber(int pageNumber, int totalPages) const;
    
    /**
     * @brief 毫米转像素
     * @param mm 毫米值
     * @param targetRect 目标矩形区域
     * @return 像素值
     */
    double mmToPixels(double mm, const QRect& targetRect) const;

    // ========== 图像处理方法组 ==========
    /**
     * @brief 应用DPI增强处理
     * @param source 源图像
     * @return 增强后的图像
     */
    QImage applyDPIEnhancement(const QImage& source) const;
    
    /**
     * @brief 应用锐化处理
     * @param source 源图像
     * @param intensity 锐化强度
     * @return 锐化后的图像
     */
    QImage applySharpening(const QImage& source, double intensity) const;

    // ========== 缩放策略方法组 ==========
    /**
     * @brief 确定最优缩放策略（内部实现）
     * @param image 源图像
     * @param viewSize 视图大小
     * @return 最优缩放策略
     */
    ZoomStrategy determineOptimalZoomStrategy(const QImage& image, const QSize& viewSize) const;
    
    /**
     * @brief 计算缩放比例（内部实现）
     * @param image 源图像
     * @param viewSize 视图大小
     * @param strategy 缩放策略
     * @return 缩放比例
     */
    double computeZoomRatio(const QImage& image, const QSize& viewSize, ZoomStrategy strategy) const;
    
    /**
     * @brief 评估是否优先使用适应宽度（内部实现）
     * @param imageRatio 图像宽高比
     * @param viewRatio 视图宽高比
     * @param image 源图像
     * @param viewSize 视图大小
     * @return 是否优先使用适应宽度
     */
    bool evaluatePreferFitWidth(double imageRatio, double viewRatio, const QImage& image, const QSize& viewSize) const;

    // ========== 多栏布局方法组 ==========
    /**
     * @brief 重新排列页面为两栏布局
     * @param originalPages 原始页面列表
     * @return 重新排列后的页面列表
     */
    QList<QImage> rearrangeForTwoColumns(const QList<QImage>& originalPages);
    
    /**
     * @brief 重新排列页面为三栏布局
     * @param originalPages 原始页面列表
     * @return 重新排列后的页面列表
     */
    QList<QImage> rearrangeForThreeColumns(const QList<QImage>& originalPages);
    
    /**
     * @brief 重新排列页面为指定栏数布局
     * @param originalPages 原始页面列表
     * @param columns 栏数
     * @param maxPagesPerColumn 每栏最大页数
     * @return 重新排列后的页面列表
     */
    QList<QImage> rearrangePagesInColumns(const QList<QImage>& originalPages, 
                                         int columns, int maxPagesPerColumn);

    // ========== 垂直流布局方法组 ==========
    /**
     * @brief 计算垂直流布局
     * @param columnImages 分栏图像列表
     * @param columns 栏数
     * @param columnWidth 栏宽度
     * @param columnSpacing 栏间距
     * @param marginTop 上边距
     * @param marginLeft 左边距
     * @param marginBottom 下边距
     * @param a4Width A4宽度
     * @param a4Height A4高度
     * @param availableHeight 可用高度
     * @param originalIndices 原始索引
     * @param outOriginalToRect 输出原始到矩形的映射
     * @param useLogicalAllocation 是否使用逻辑分配
     * @return 布局矩形列表
     */
    QVector<QRect> computeVerticalFlowLayout(const QList<QList<QImage>>& columnImages,
                                           int columns, int columnWidth, int columnSpacing,
                                           int marginTop, int marginLeft, int marginBottom,
                                           int a4Width, int a4Height, int availableHeight,
                                           const QVector<int>* originalIndices,
                                           QHash<int, QRect>* outOriginalToRect,
                                           bool useLogicalAllocation = false) const;

    // ========== 页面组合方法组 ==========
    /**
     * @brief 组合多栏页面
     * @param originalPages 原始页面列表
     * @param compositeIndex 组合索引
     * @param mode 布局模式
     * @return 组合后的页面图像
     */
    QImage composeMultiColumnPage(const QList<QImage>& originalPages, int compositeIndex, LayoutMode mode);
    
    /**
     * @brief 渲染垂直流组合
     * @param columnImages 分栏图像列表
     * @param columnImageWidths 分栏图像宽度列表
     * @param columns 栏数
     * @param columnWidth 栏宽度
     * @param columnSpacing 栏间距
     * @param marginTop 上边距
     * @param marginLeft 左边距
     * @param marginBottom 下边距
     * @param a4Width A4宽度
     * @param a4Height A4高度
     * @param availableHeight 可用高度
     * @param originalIndices 原始索引
     * @param outOriginalToRect 输出原始到矩形的映射
     * @return 渲染后的图像
     */
    QImage renderVerticalFlowComposition(const QList<QList<QImage>>& columnImages,
                                       const QList<int>& columnImageWidths,
                                       int columns, int columnWidth, int columnSpacing,
                                       int marginTop, int marginLeft, int marginBottom,
                                       int a4Width, int a4Height, int availableHeight,
                                       const QVector<int>* originalIndices,
                                       QHash<int, QRect>* outOriginalToRect);

    // ========== 高亮功能方法组 ==========
    /**
     * @brief 计算高亮矩形区域（内部实现）
     * @param pageWidth 页面宽度
     * @param pageHeight 页面高度
     * @param currentPage 当前页面索引
     * @return 高亮矩形区域
     */
    QRect computeHighlightRect(int pageWidth, int pageHeight, int currentPage) const;
    
    /**
     * @brief 渲染高亮矩形（内部实现）
     * @param painter 绘制器
     * @param pageRect 页面矩形区域
     * @param currentPage 当前页面索引
     */
    void renderHighlightRectangles(QPainter* painter, const QRect& pageRect, int currentPage) const;

    // ========== 预览渲染方法组 ==========
    /**
     * @brief 生成预览图像（内部实现）
     * @param originalImage 原始图像
     * @param pageIndex 页面索引
     * @param targetSize 目标尺寸
     * @return 预览图像
     */
    QImage generatePreviewImage(const QImage& originalImage, int pageIndex, const QSize& targetSize, int totalPages = 0) const;
    
    /**
     * @brief 生成导出图像（内部实现）
     * @param originalImage 原始图像
     * @param pageIndex 页面索引
     * @return 导出图像
     */
    QImage generateExportImage(const QImage& originalImage, int pageIndex, int totalPages = 0) const;

    // ========== 占位符绘制方法组 ==========
    /**
     * @brief 绘制美观的占位符
     * @param painter 绘制器
     * @param size 尺寸
     * @param pageIndex 页面索引
     * @param x X坐标
     * @param y Y坐标
     */
    void drawBeautifulPlaceholder(QPainter* painter, const QSize& size, int pageIndex, int x, int y);

    // ========== 成员变量 ==========
    /**
     * @brief 高亮功能私有成员（从PageView迁移）
     */
    int m_highlightedThumbnailIndex;    ///< 高亮的缩略图索引
    int m_totalThumbnails;              ///< 总缩略图数量
    int m_columnMode;                   ///< 栏模式
    bool m_hasHighlight;                ///< 是否有高亮
    QHash<int, QHash<int, QRect>> m_accurateLayoutRects;  ///< 精确布局矩形

    /**
     * @brief 核心成员变量
     */
    const ProcessingSettings* m_settings;  ///< 处理设置
    QImage m_pageContent;                  ///< 页面内容

      // === 私有方法：Martin Fowler重构 ===

    /**
     * 传统渲染方法（降级使用）
     */
    void renderToWidgetLegacy(QPainter* painter, const QRect& targetRect, const QImage& content,
                             int pageNumber, int totalPages);
    void renderToPDFLegacy(QPdfWriter* writer, QPainter* painter, const QImage& content,
                          int pageNumber, int totalPages);
    void renderToPDFLegacyDirect(QPdfWriter* writer, QPainter* painter, int pageNumber, int totalPages);

    /**
     * @brief 常量定义
     */
    static const double A4_WIDTH_MM;   ///< A4宽度（毫米）
    static const double A4_HEIGHT_MM;  ///< A4高度（毫米）
};

#endif // UNIFIEDPAGERENDERER_H